The present invention relates generally to computer graphics, and particularly to generating images using MIP maps.
In modern computer graphics systems, a given image may be drawn at a multitude of sizes. For example, to produce an image of a field of tulips, the system may generate an image of a tulip, and then draw the image many times to produce the field. Tulips in the foreground are drawn at a large size, while tulips in the background are drawn at a much smaller size due to their greater distance from the viewer. However, if each tulip image has the same number of pixels, the large tulips may appear blurry while the small tulips may be aliased.
In order to address these problems, and to speed generation of such a display, conventional systems employ a technique called “MIP mapping.” The term MIP derives from the Latin phrase “multum in parvum” which means “many things in a small place.” According to this technique, multiple versions of the tulip image are generated before rendering the image of the field of tulips. Each version is of a different size and includes an appropriate number of pixels to prevent blurring or aliasing when rendered at that size. Each version is said to be at a different MIP map level of detail (LOD). Together the versions constitute the MIP map for the tulip image.
With MIP mapping, a tulip of a certain size can be drawn by simply selecting the appropriate MIP map LOD. Each LOD is assigned a sequential number, with zero assigned to the LOD having the largest number of pixels (referred to as the “base LOD” or “base image”). Then a particular LOD can be selected by merely specifying its number. Some scaling of the selected LOD is still usually required. But because the selected LOD is close to the right size, only minimal scaling is necessary, thus reducing the time required to scale and the possibility of scaling errors.
Usually a high-resolution base image is subsampled in each dimension by a factor of 2, often all the way down to 1×1 pixels, to create the LODs. When map dimensions are powers of two, it's easy to find the beginning (and end) of a given LOD in memory given a base memory address. Otherwise, a more complex technique is required. One conventional solution is to calculate the amount of storage space for each LOD by simply multiplying the dimensions of that LOD to obtain the size of that LOD. Because the multiply is a time-consuming operation, these calculations are not performed at run time as each LOD is selected. Instead, the calculations are performed in advance to create an array of pointers. Each pointer points to the beginning memory address of one of the LODs. Then during run time, when a LOD is needed, the number of the LOD is used to index the array, which produces a pointer to the beginning address of that LOD in memory. One disadvantage of this technique is that a significant amount of memory is required simply to store the array of pointers. Another disadvantage is that significant time is required to use the array at run time.